package com.chinalife.project.advice;

import com.chinalife.project.entity.ResponseEntity;
import com.chinalife.project.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

import java.nio.file.AccessDeniedException;

/**
 * @author 18101119
 * @description 统一异常处理
 * @date 2024/3/25 13:59
 * @email songxinhang2023@e-chinalife.com
 * @id 18101119
 * @phone 13001321080
 */
@Slf4j
@RestControllerAdvice
public class ExceptionHandlerAdvice {

    /**
     * @author synhard
     * @id 18101119
     * @description 参数格式异常处理
     * @date 2024/3/25 17:04
     * @param ex 异常
     * @return com.chinalife.cdp.entity.ResponseEntity<java.lang.String>
     */
    @ExceptionHandler({IllegalArgumentException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseEntity<String> badRequestException(IllegalArgumentException ex) {
        log.error("参数格式不合法：{}", ex.getMessage());
        return new ResponseEntity<>(HttpStatus.BAD_REQUEST.value(), "参数格式不符！", MDC.get("traceId"));
    }

    /**
     * @author synhard
     * @id 18101119
     * @description 权限异常处理
     * @date 2024/3/25 17:04
     * @param ex 异常
     * @return com.chinalife.cdp.entity.ResponseEntity<java.lang.String>
     */
    @ExceptionHandler({AccessDeniedException.class})
    @ResponseStatus(HttpStatus.FORBIDDEN)
    public ResponseEntity<String> badRequestException(AccessDeniedException ex) {
        return new ResponseEntity<>(HttpStatus.FORBIDDEN.value(), ex.getMessage(), MDC.get("traceId"));
    }

    /**
     * @author synhard
     * @id 18101119
     * @description 参数缺失异常处理
     * @date 2024/3/25 17:04
     * @param ex 异常
     * @return com.chinalife.cdp.entity.ResponseEntity<java.lang.String>
     */
    @ExceptionHandler({MissingServletRequestParameterException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseEntity<String> badRequestException(Exception ex) {
        return ResponseEntity.fail(HttpStatus.BAD_REQUEST.value(), "缺少必填参数！", MDC.get("traceId"));
    }

    /**
     * @author synhard
     * @id 18101119
     * @description 空指针异常
     * @date 2024/3/25 17:05
     * @param ex 异常
     * @return com.chinalife.cdp.entity.ResponseEntity<java.lang.String>
     */
    @ExceptionHandler(NullPointerException.class)
    @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
    public ResponseEntity<String> handleTypeMismatchException(NullPointerException ex) {
        log.error("空指针异常，{}", ex.getMessage());
        return ResponseEntity.fail("空指针异常", MDC.get("traceId"));
    }

    /**
     * @author synhard
     * @id 18101119
     * @description 参数不匹配
     * @date 2024/3/25 17:05
     * @param ex 异常
     * @return com.chinalife.cdp.entity.ResponseEntity<java.lang.String>
     */
    @ExceptionHandler(MethodArgumentTypeMismatchException.class)
    @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
    public ResponseEntity<String> methodArgTypeMismatchException(NullPointerException ex) {
        log.error("参数不匹配，{}", ex.getMessage());
        return ResponseEntity.fail("参数不匹配", MDC.get("traceId"));
    }

    /**
     * @author synhard
     * @id 18101119
     * @description 其他异常
     * @date 2024/3/25 17:05
     * @param ex 异常
     * @return com.chinalife.cdp.entity.ResponseEntity<java.lang.String>
     */
    @ExceptionHandler(Exception.class)
    @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
    public ResponseEntity<String> handleUnexpectedServer(Exception ex) {
        log.error("系统异常：", ex);
        return ResponseEntity.fail(HttpStatus.INTERNAL_SERVER_ERROR.value(), ex.getMessage(), MDC.get("traceId"));
    }

    /**
     * @author synhard
     * @id 18101119
     * @description 业务异常
     * @date 2024/3/25 17:06
     * @param ex 业务异常
     * @return com.chinalife.cdp.entity.ResponseEntity<java.lang.String>
     */
    @ExceptionHandler(BusinessException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ResponseEntity<String> handleBusinessException(Exception ex) {
        log.error("业务逻辑异常", ex);
        return ResponseEntity.fail(HttpStatus.INTERNAL_SERVER_ERROR.value(), ex.getMessage(), MDC.get("traceId"));
    }

    /**
     * @author synhard
     * @id 18101119
     * @description 系统异常处理
     * @date 2024/3/25 17:06
     * @param throwable 系统异常
     * @return com.chinalife.cdp.entity.ResponseEntity<java.lang.String>
     */
    @ExceptionHandler(Throwable.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ResponseEntity<String> exception(Throwable throwable) {
        log.error("系统异常", throwable);
        return ResponseEntity.fail(HttpStatus.INTERNAL_SERVER_ERROR.value(), "系统异常，请联系管理员！", MDC.get("traceId"));
    }
}